/**
 * 5种操作：
 * 1 L R x: 区间增加x
 * 2 L R: 判断区间是否全相同
 * 3 L R: 判断区间是否严格升序
 * 4 L R: 判断区间是否严格降序
 * 5 L R: 判断是否单峰，单峰长度必然大于等于3，且必然有一个分界点，左边严格升，右边严格降
 * 
 * 记录最小值、最大值、左右边界和状态即可
 * 状态分为5种，即：升、降、峰、乱、单（专指只有一个元素的情况）
 * 然后在pushUp的时候处理好各种状态即可
 * 延迟操作的实现比较简单，就是区间增加
 * 依据查询到的数据，回答问题即可
 * 标程维护的是差分数组，感觉不需要
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;


using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
llt const MOD = 998244353LL;

llt const INF = 0x7F1F2F3F4F5F6F8F;
llt const NINF = -INF;

struct SegTree{ // 线段树带延迟

using llt = long long;

int N;

struct _t{
    llt min;
    llt max;
    llt left;
    llt right;
    int status; // 1升 2降 3峰 4乱 5单
};

using value_type = _t;
vector<value_type> data; // 线段树

using lazy_type = llt;
vector<lazy_type> lazy; // 延迟标记

/// 从下往上计算信息，要变动
value_type _up_(const value_type & ls, const value_type & rs) {
    if(ls.status == 0) return rs;
    if(rs.status == 0) return ls;

    value_type ret;
    ret.min = min(ls.min, rs.min);
    ret.max = max(ls.max, rs.max);
    ret.left = ls.left;
    ret.right = rs.right;
    switch(ls.status){
        case 1:{
            if(1 == rs.status){
                ret.status = (ls.right < rs.left) ? 1 : 4;
            }else if(2 == rs.status){
                ret.status = (ls.right != rs.left) ? 3 : 4;
            }else if(3 == rs.status){
                ret.status = (ls.right < rs.left) ? 3 : 4;
            }else if(4 == rs.status){
                ret.status = 4;
            }else if(5 == rs.status){
                assert(rs.left == rs.right);
                if(ls.right < rs.left) ret.status = 1;
                else if(ls.right > rs.left) ret.status = 3;
                else ret.status = 4;
            }else{
                assert(0);
            }
            break;
        }
        case 2:{
            if(1 == rs.status){
                ret.status = 4;
            }else if(2 == rs.status){
                ret.status = (ls.right > rs.left) ? 2 : 4;
            }else if(3 == rs.status){
                ret.status = 4;
            }else if(4 == rs.status){
                ret.status = 4;
            }else if(5 == rs.status){
                assert(rs.right == rs.left);
                ret.status = (ls.right > rs.left) ? 2 : 4;
            }else{
                assert(0);
            }
            break;
        }
        case 3:{
            if(1 == rs.status){
                ret.status = 4;
            }else if(2 == rs.status){
                ret.status = (ls.right > rs.left) ? 3 : 4;
            }else if(3 == rs.status){
                ret.status = 4;
            }else if(4 == rs.status){
                ret.status = 4;
            }else if(5 == rs.status){
                assert(rs.left == rs.right);
                ret.status = (ls.right > rs.left) ? 3 : 4;
            }else{
                assert(0);
            }
            break;
        }
        case 4:{
            if(1 == rs.status){
                ret.status = 4;
            }else if(2 == rs.status){
                ret.status = 4;
            }else if(3 == rs.status){
                ret.status = 4;
            }else if(4 == rs.status){
                ret.status = 4;
            }else if(5 == rs.status){
                ret.status = 4;
            }else{
                assert(0);
            }
            break;
        }
        case 5:{
            assert(ls.left == ls.right);
            if(1 == rs.status){
                ret.status = (ls.right < rs.left) ? 1 : 4; 
            }else if(2 == rs.status){
                if(ls.right > rs.left) ret.status = 2;
                else if(ls.right < rs.left) ret.status = 3;
                else ret.status = 4;
            }else if(3 == rs.status){
                ret.status = (ls.right < rs.left) ? 3 : 4; 
            }else if(4 == rs.status){
                ret.status = 4;
            }else if(5 == rs.status){
                if(ls.right > rs.left) ret.status = 2;
                else if(ls.right < rs.left) ret.status = 1;
                else ret.status = 4;
            }else{
                assert(0);
            }
            break;
        }
        default:assert(0);
    }
    return ret;
}

// 根据变动信息delta计算本节点的信息并且打延迟标记，用于pushDown或者modify
// 这里只计算t，跟t的儿子无关
// 要计算data[t]和lazy[t]
void _dn_(int t, int s, int e, const lazy_type & delta) {
    data[t].left += delta;
    data[t].right += delta;
    data[t].min += delta;
    data[t].max += delta;
    lazy[t] += delta;
    return;
}

/// 初始化，清零，不用动
void init(int n) {
    data.assign((N = n) + 1 << 2, value_zero());
    lazy.assign(n + 1 << 2, lazy_zero());
}

/// 这个函数不用动
void modify(int a, int b, const lazy_type & delta){
    _modify(1, 1, N, a, b, delta);
}

/// 这个函数不用动
value_type query(int a, int b){
    return _query(1, 1, N, a, b);
}

/// 这个函数不用动
void build() {
    _build(1, 1, N);
}

/// 几乎不用动
value_type _query(int t, int s, int e, int a, int b) {
    if(a <= s and e <= b) {
        return data[t];
    }
    _pushDown(t, s, e);
    int mid = (s + e) >> 1;
    value_type ans = value_zero(); // 如果求最值，这里不能用zero
    if(a <= mid) ans = _up_(ans, _query(lson(t), s, mid, a, b));
    if(mid < b) ans = _up_(ans, _query(rson(t), mid + 1, e, a, b));
    return ans;
}

/// 几乎不用动
void _modify(int t, int s, int e, int a, int b, const lazy_type & delta) {
    if(a <= s and e <= b) {
        _dn_(t, s, e, delta);
        return;
    }
    _pushDown(t, s, e);
    int mid = (s + e) >> 1;
    if(a <= mid) _modify(lson(t), s, mid, a, b, delta);
    if(mid < b) _modify(rson(t), mid + 1, e, a, b, delta);
    _pushUp(t);
    return;
}

/// 这个函数不用动
void _pushUp(int t) {
    data[t] = _up_(data[lson(t)], data[rson(t)]);
}

/// 这个函数几乎不用动
void _pushDown(int t, int s, int e) {
    if(lazy_zero() == lazy[t]) return;
    auto & lz = lazy[t];
    auto ls = lson(t), rs = rson(t);
    int mid = (s + e) >> 1;

    _dn_(ls, s, mid, lz);
    _dn_(rs, mid + 1, e, lz);

    lz = lazy_zero();
}


/// 几乎不用动
void _build(int t, int s, int e) {
    if(s == e) {
        llt x; cin >> x;
        data[t] = {x, x, x, x, 5}; // 注意提供value_type的初始化
        return; 
    }
    int mid = (s + e) >> 1;
    _build(lson(t), s, mid);
    _build(rson(t), mid + 1, e);
    _pushUp(t);
}

/// 辅助函数，视延迟的类型而变动
static const lazy_type & lazy_zero() {
    static const lazy_type LAZY0 = 0;
    return LAZY0; 
}

/// 辅助函数，视线段树信息类型而变动
static const value_type & value_zero() {
    static const value_type VALUE0 = {INF, NINF, 0LL, 0LL, 0};
    return VALUE0;
}

/// 这两个函数不用变动
static int lson(int x) {return x << 1;}
static int rson(int x) {return lson(x) | 1;}

void disp()const{
    _disp(1, 1, N);
}

void _disp(int t, int s, int e)const{
    cout << "Node " << t << ", [" << s << ", " << e << "]:" << endl;
    cout << "min = " << data[t].min << ", max = " << data[t].max << ", left = " << data[t].left << ", right = " << data[t].right << ", status = " << data[t].status << endl;
    cout << "lazy = " << lazy[t] << endl;    
    if(s == e){
        return;
    }
    int mid = (s + e) >> 1;
    _disp(lson(t), s, mid);
    _disp(rson(t), mid + 1, e);
}

};


SegTree St;
int N;
vll A;
int Q;

void work(){ 
    cin >> N;
    St.init(N);
    St.build();

    // cout << "Init:" << endl;
    // St.disp();

    cin >> Q;
    for(int c,a,b,q=1;q<=Q;++q){
        cin >> c >> a >> b;
        if(1 == c){
            llt x; cin >> x;
            St.modify(a, b, x);

            // cout << "ModifY: " << q << endl;
            // St.disp();
        }else{
            auto ans = St.query(a, b);
            assert(ans.status);
            if(2 == c){ 
                cout << (ans.min == ans.max ? 1 : 0) << "\n";
            }else if(3 == c){
                cout << (5 == ans.status or 1 == ans.status ? 1 : 0) << "\n";
            }else if(4 == c){
                cout << (5 == ans.status or 2 == ans.status ? 1 : 0) << "\n";
            }else if(5 == c){
                cout << (3 == ans.status ? 1 : 0) << "\n";
            }else{
                assert(0);
            }
        }    
    }
	return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}